/*
 * COPYRIGHT. ShenZhen JiMi Technology Co., Ltd. 2017.
 * ALL RIGHTS RESERVED.
 *
 * No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
 * on any form or by any means, electronic, mechanical, photocopying, recording, 
 * or otherwise, without the prior written permission of ShenZhen JiMi Network Technology Co., Ltd.
 *
 * Amendment History:
 * 
 * Date                   By              Description
 * -------------------    -----------     -------------------------------------------
 * 2017年4月10日    li.shangzhi         Create the class
 * http://www.jimilab.com/
 */

package com.jimi.api.auth.controller;

import javax.servlet.http.HttpServletRequest;

import net.sf.oval.constraint.Length;
import net.sf.oval.constraint.MatchPattern;
import net.sf.oval.constraint.MemberOf;
import net.sf.oval.constraint.NotBlank;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.jimi.api.auth.OAuthApi;
import com.jimi.api.auth.vo.AccessTokenVo;
import com.jimi.app.dto.output.ApiAppInfoOutputDto;
import com.jimi.exception.ErrorCode;
import com.jimi.exception.SysApiException;
import com.jimi.framework.base.BaseController;
import com.jimi.framework.bean.BeanUtil;
import com.jimi.framework.utils.DESEncrypt;
import com.jimi.framework.utils.ResultModel;
import com.jimi.web.api.IOAuthApiService;
import com.jimi.web.api.IUserApiService;
import com.jimi.web.dto.output.AccessTokenOutputDto;
import com.jimi.web.dto.output.CoreUserOutputDto;

/**
 * @FileName OAuthApiController.java
 * @Description:
 *
 * @Date 2017年4月10日 下午4:36:28
 * @author li.shangzhi
 * @version 1.0
 */
@RestController
@RequestMapping(value = "/oauth")
public class OAuthApiController extends BaseController implements OAuthApi {

	@Autowired
	private IOAuthApiService oauthApiService;
	
	@Autowired
	private IUserApiService userApiService;

	@ResponseBody
	@RequestMapping(value = "/getAppkeyAndSecret", params = { "method=jimi.oauth.appkey.create" }, produces = { "application/json" }, method = {
			RequestMethod.GET, RequestMethod.POST })
	@Override
	public ResponseEntity<ResultModel> getAppkeyAndSecret(
//			@NotBlank(message = "api.method.invalid") @Length(min = 10, max = 20, message = "api.method.invalid") @RequestParam(value = "method", required = true) String method,
//			@NotBlank(message = "api.appkey.invalid") @Length(min = 10, max = 32, message = "api.appkey.invalid") @RequestParam(value = "app_key", required = true) String appKey,
//			@NotBlank(message = "api.timestamp.invalid") @DateRange(format = "yyyy-MM-dd HH:mm:ss", message = "api.timestamp.invalid") @RequestParam(value = "timestamp", required = true) String timestamp,
//			@NotBlank(message = "api.format.invalid") @MemberOf(value = { "json", "xml" }, message = "api.format.invalid") @RequestParam(value = "format", required = true) String format,
//			@NotBlank(message = "api.version.invalid") @MemberOf(value = { "1.0" }, message = "api.version.invalid") @RequestParam(value = "v", required = true) String v,
//			@NotBlank(message = "api.signmethod.invalid") @MemberOf(value = { "md5" }, message = "api.signmethod.invalid") @RequestParam(value = "sign_method", required = true) String signMethod,
//			@NotBlank(message = "api.sign.invalid") @Length(min = 10, max = 32, message = "api.sign.invalid") @RequestParam(value = "sign", required = true) String sign,
			@NotBlank(message = "api.userId.invalid") @Length(min = 3, max = 32, message = "api.userId.invalid") @RequestParam(value = "user_id", required = true) String account,
			@NotBlank(message = "api.userPwd.invalid") @Length(min = 3, max = 32, message = "api.userPwd.invalid") @RequestParam(value = "user_pwd", required = true) String userPwd,
			@NotBlank(message = "api.projectCode.invalid") @MemberOf(value = { "TUQIANG" }, message = "api.projectCode.invalid") @RequestParam(value = "project_code", required = true) String projectCode,
			@RequestParam(value = "app_desc", required = false) String appDesc,	HttpServletRequest request) {
		ApiAppInfoOutputDto outputDto = oauthApiService.getAppkeyAndSecret(account, userPwd, projectCode, appDesc);
		if(null == outputDto) {
			return new ResponseEntity<>(new ResultModel(ErrorCode.INVALID_USER_ERROR), HttpStatus.OK);
		}
		ResultModel resultModel = new ResultModel();
		resultModel.setResult(outputDto);
		return new ResponseEntity<>(resultModel, HttpStatus.OK);
	}

	@ResponseBody
	@RequestMapping(value = "/getAccessToken", params = { "method=jimi.oauth.token.get" }, produces = { "application/json" }, method = {
			RequestMethod.GET, RequestMethod.POST })
	@Override
	public ResponseEntity<ResultModel> getAccessToken(
//			@NotBlank(message = "api.method.invalid") @Length(min = 10, max = 20, message = "api.method.invalid") @RequestParam(value = "method", required = true) String method,
			@NotBlank(message = "api.appkey.invalid") @Length(min = 10, max = 32, message = "api.appkey.invalid") @RequestParam(value = "app_key", required = true) String appKey,
//			@NotBlank(message = "api.timestamp.invalid") @DateRange(format = "yyyy-MM-dd HH:mm:ss", message = "api.timestamp.invalid") @RequestParam(value = "timestamp", required = true) String timestamp,
//			@NotBlank(message = "api.format.invalid") @MemberOf(value = { "json", "xml" }, message = "api.format.invalid") @RequestParam(value = "format", required = true) String format,
//			@NotBlank(message = "api.version.invalid") @MemberOf(value = { "1.0" }, message = "api.version.invalid") @RequestParam(value = "v", required = true) String v,
//			@NotBlank(message = "api.signmethod.invalid") @MemberOf(value = { "md5" }, message = "api.signmethod.invalid") @RequestParam(value = "sign_method", required = true) String signMethod,
//			@NotBlank(message = "api.sign.invalid") @Length(min = 10, max = 32, message = "api.sign.invalid") @RequestParam(value = "sign", required = true) String sign,
			@NotBlank(message = "api.userId.invalid") @Length(min = 3, max = 32, message = "api.userId.invalid") @RequestParam(value = "user_id", required = true) String account,
			@NotBlank(message = "api.userPwd.invalid") @Length(min = 3, max = 32, message = "api.userPwd.invalid") @RequestParam(value = "user_pwd_md5", required = true) String userPwd,
			@NotBlank(message = "api.expiresIn.invalid") @MatchPattern(matchAll = false, pattern = { "^[6-9]\\d|\\d{3}|[1-6]\\d{3}|[7][0-1]\\d{2}|7200$" }, message = "api.expiresIn.invalid") @RequestParam(value = "expires_in", required = true) int expiresIn,
			HttpServletRequest request) {
		String decrypt = DESEncrypt.decrypt(appKey);
		String[] strs = decrypt.split(",");
		String projectCode = strs[0];
		String curUserId = strs[1];
		CoreUserOutputDto coreUserOutputDto = userApiService.checkUserRange(curUserId, account);
		if(null == coreUserOutputDto) {
			return new ResponseEntity<ResultModel>(new ResultModel(ErrorCode.INVALID_USER_ERROR), HttpStatus.OK);
		}
		if (!userPwd.equals(coreUserOutputDto.getPassword())) {
			return new ResponseEntity<ResultModel>(new ResultModel(ErrorCode.INVALID_USER_ERROR), HttpStatus.OK);
		}
		try {
			String userId = String.valueOf(coreUserOutputDto.getId());
			AccessTokenOutputDto tokenOutputDto = oauthApiService.createAccessToken(appKey, userId, account, expiresIn);
			if(null == tokenOutputDto) {
				return new ResponseEntity<>(new ResultModel(ErrorCode.INVALID_USER_ERROR), HttpStatus.OK);
			}
			ResultModel resultModel = new ResultModel();
			resultModel.setResult(BeanUtil.convertBean(tokenOutputDto, AccessTokenVo.class));
			return new ResponseEntity<>(resultModel, HttpStatus.OK);
		} catch (SysApiException apiEx) {
			return new ResponseEntity<>(new ResultModel(apiEx.getErrorCode()), HttpStatus.OK);
		}
	}

	@ResponseBody
	@RequestMapping(value = "/refreshAccessToken", params = { "method=jimi.oauth.token.refresh" }, produces = { "application/json" }, method = {
			RequestMethod.GET, RequestMethod.POST })
	@Override
	public ResponseEntity<ResultModel> refreshAccessToken(
//			@NotBlank(message = "api.method.invalid") @Length(min = 10, max = 20, message = "api.method.invalid") @RequestParam(value = "method", required = true) String method,
			@NotBlank(message = "api.appkey.invalid") @Length(min = 10, max = 32, message = "api.appkey.invalid") @RequestParam(value = "app_key", required = true) String appKey,
//			@NotBlank(message = "api.timestamp.invalid") @DateRange(format = "yyyy-MM-dd HH:mm:ss", message = "api.timestamp.invalid") @RequestParam(value = "timestamp", required = true) String timestamp,
//			@NotBlank(message = "api.format.invalid") @MemberOf(value = { "json", "xml" }, message = "api.format.invalid") @RequestParam(value = "format", required = true) String format,
//			@NotBlank(message = "api.version.invalid") @MemberOf(value = { "1.0" }, message = "api.version.invalid") @RequestParam(value = "v", required = true) String v,
//			@NotBlank(message = "api.signmethod.invalid") @MemberOf(value = { "md5" }, message = "api.signmethod.invalid") @RequestParam(value = "sign_method", required = true) String signMethod,
//			@NotBlank(message = "api.sign.invalid") @Length(min = 10, max = 32, message = "api.sign.invalid") @RequestParam(value = "sign", required = true) String sign,
			@NotBlank(message = "api.accessToken.invalid") @Length(min = 32, max = 32, message = "api.accessToken.invalid") @RequestParam(value = "access_token", required = true) String accessToken,
			@NotBlank(message = "api.accessToken.invalid") @Length(min = 32, max = 32, message = "api.accessToken.invalid") @RequestParam(value = "refresh_token", required = true) String refreshToken,
			@NotBlank(message = "api.expiresIn.invalid") @MatchPattern(matchAll = false, pattern = { "^[6-9]\\d|\\d{3}|[1-6]\\d{3}|[7][0-1]\\d{2}|7200$" }, message = "api.expiresIn.invalid") @RequestParam(value = "expires_in", required = true) int expiresIn,
			HttpServletRequest request) {
		String decrypt = DESEncrypt.decrypt(appKey);
		String[] strs = decrypt.split(",");
		String projectCode = strs[0];
		String curUserId = strs[1];
		try {
			AccessTokenOutputDto tokenOutputDto = oauthApiService.refreshAccessToken(accessToken, refreshToken, expiresIn);
			if(null == tokenOutputDto) {
				return new ResponseEntity<>(new ResultModel(ErrorCode.TOKEN_ERROR), HttpStatus.OK);
			}
			ResultModel resultModel = new ResultModel();
			resultModel.setResult(BeanUtil.convertBean(tokenOutputDto, AccessTokenVo.class));
			return new ResponseEntity<>(resultModel, HttpStatus.OK);
		} catch (SysApiException apiEx) {
			return new ResponseEntity<>(new ResultModel(apiEx.getErrorCode()), HttpStatus.OK);
		}
	}
}
